package com.open.common.controller;

import java.util.HashMap;
import java.util.Map;

import javax.el.MethodNotFoundException;

import com.open.common.exception.BaseException;
import com.open.common.exception.DAOException;
import com.open.common.exception.ValidateException;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public abstract class AbstractSimpleController extends AbstractBaseController {
    private static final Logger LOG = Logger.getLogger(AbstractSimpleController.class);

    @ExceptionHandler({Exception.class})
    protected ResponseEntity<Object> handleException(Exception e) {
        LOG.error("server error", e);
        return new ResponseEntity<Object>(buildErrorMsg(e), HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler({ValidateException.class})
    protected ResponseEntity<Object> handleValidateException(ValidateException e) {
        LOG.error("validate error", e);
        return new ResponseEntity<Object>(buildErrorMsg(e), HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler({NoSuchMethodException.class})
    protected ResponseEntity<Object> handleNoSuchMethodException(NoSuchMethodException e) {
        LOG.error("execute script error", e);
        return new ResponseEntity<Object>(buildErrorMsg(e), HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @ExceptionHandler({MethodNotFoundException.class})
    protected ResponseEntity<Object> handleMethodNotFoundException(MethodNotFoundException e) {
        LOG.error("validate error", e);
        return new ResponseEntity<Object>(buildErrorMsg(e), HttpStatus.NOT_FOUND);
    }

    @ExceptionHandler({DAOException.class})
    protected ResponseEntity<Object> handleMethodNotFoundException(DAOException e) {
        LOG.error("DAO error", e);
        return new ResponseEntity<Object>(buildErrorMsg(e), HttpStatus.INTERNAL_SERVER_ERROR);
    }

    private Map<String, Object> buildErrorMsg(Exception ex) {
        Map<String, Object> msg = new HashMap<String, Object>();
        if (StringUtils.isNotEmpty(ex.getMessage())) {
            if (ex instanceof BaseException) {
                BaseException bex = (BaseException) ex;
                msg.put("code", bex.getNumber());
            }
            msg.put("error", ex.getMessage());
        } else {
            msg.put("error", ex.toString());
        }
        return msg;
    }

    // 处理参数校验异常
    public void processPramValidError(BindingResult br) {
        // 参数校验
        if (br.hasErrors()) {
            StringBuffer msg = new StringBuffer("参数校验失败，校验结果为：");
            for (ObjectError error : br.getAllErrors()) {
                msg.append(error.getDefaultMessage());
            }
            throw new ValidateException(msg.toString());
        }
    }

}
